import {
  Button,
  DatePicker,
  Divider,
  Form,
  FormItem,
  Input,
  message,
  RangePicker,
  Select,
  SelectOption,
  Space,
  Spin,
  Upload
} from 'ant-design-vue'
import { omit, trim } from 'lodash-es'
import moment, { Moment } from 'moment'
import { computed, defineComponent, nextTick, onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'

import { commonApi, couponApi, marketingApi } from '@/apis'
import {
  type ProEditorProps,
  type ProEditorRef,
  ProEditor,
  SvgIcon
} from '@/components'
import { useBack } from '@/hooks'

import styles from './index.module.css'

type UploadKey = 'sharePosterImg' | 'goodsImg'

const { useForm } = Form

export default defineComponent({
  name: 'GroupForm',
  props: {
    isView: {
      type: Boolean,
      default: false
    }
  },
  setup(props) {
    const loading = ref(false)
    const formModel = ref({
      name: '',
      activityStartTime: '',
      activityEndTime: '',
      expireTime: 24,
      groupNumber: '',
      sort: 999,
      groupCoupon: undefined,
      stock: '',
      price: '',
      groupPrice: '',
      robotFillTime: '',
      robotNum: '',
      robotRatio: '',
      sharePosterImg: '',
      goodsImg: '',
      goodsDescription: '',
      amalgamateGroupLimit: 0,
      openGroupLimit: 0
    })
    const formRules = ref({
      name: [{ required: true, message: '请输入', trigger: 'blur' }],
      activityDate: [
        {
          validator: () => {
            if (!formModel.value.activityStartTime) {
              return Promise.reject('请选择开始日期')
            }

            if (!formModel.value.activityEndTime) {
              return Promise.reject('请选择结束日期')
            }

            return Promise.resolve()
          }
        }
      ],
      expireTime: [{ required: true, validator: integerValidator }],
      groupNumber: [
        { required: true, validator: groupNumberValidator, trigger: 'blur' }
      ],
      sort: [{ required: true, validator: integerValidator }],
      groupCoupon: [{ required: true, message: '请选择' }],
      stock: [{ required: true, validator: integerValidator }],
      price: [{ required: true, validator: amountValidator, trigger: 'blur' }],
      groupPrice: [
        { required: true, validator: amountValidator, trigger: 'blur' }
      ],
      sharePosterImg: [
        {
          required: true,
          validator: () => {
            if (fileList.value.sharePosterImg.length === 0) {
              return Promise.reject('请上传')
            }

            return Promise.resolve()
          }
        }
      ],
      goodsImg: [
        {
          required: true,
          validator: () => {
            if (fileList.value.goodsImg.length === 0) {
              return Promise.reject('请上传')
            }

            return Promise.resolve()
          }
        }
      ],
      goodsDescription: [
        { required: true, message: '请输入', trigger: 'blur' }
      ],
      amalgamateGroupLimit: [
        { required: true, validator: integerValidator, trigger: 'blur' }
      ],
      openGroupLimit: [
        { required: true, validator: integerValidator, trigger: 'blur' }
      ]
    } as FormRules)
    const editorRef = ref({} as ProEditorRef)
    const editorConfig = ref({
      wrapStyle: {
        width: '702px'
      },
      editorStyle: {
        height: '300px'
      },
      editorHtml: '',
      editorVisible: false,
      editorConfig: {
        MENU_CONF: {
          uploadImage: {
            server: commonApi.uploadFileUrl,
            fieldName: 'file',
            customInsert(res: any, insertFn: any) {
              // res 即服务端的返回结果
              const url = res.data

              // 从 res 中找到 url alt href ，然后插图图片
              insertFn(url, '', '')
            }
          }
        } as any
      },
      toolbarConfig: {
        excludeKeys: ['group-video']
      }
    } as ProEditorProps)
    const couponOptions = ref([] as OptionItem[])
    const couponStockMap = ref({})
    const fileList = ref({
      sharePosterImg: [] as any[],
      goodsImg: [] as any[]
    })

    const formRef = useForm(formModel, formRules)
    const route = useRoute()
    const { handleCancel } = useBack('refreshGroupManageList')

    const id = computed(() => Number(route.query.id))
    const isPending = computed(() => Boolean(route.query.pending))

    const isDisabled = computed(() => props.isView)

    function groupNumberValidator(rule, value) {
      if (value === '') {
        return Promise.reject('请输入')
      }

      if (!/^\+?[1-9]\d*$/.test(value)) {
        return Promise.reject('请输入大于0的整数')
      }

      return Promise.resolve()
    }

    function integerValidator(rule, value) {
      if (value === '') {
        return Promise.reject('请输入')
      }

      if (isNaN(Number(value)) || !Number.isInteger(Number(value))) {
        return Promise.reject('请输入整数')
      }

      return Promise.resolve()
    }

    function amountValidator(rule, value) {
      if (value === '' || value === null) {
        return Promise.reject('请输入')
      }

      if (isNaN(Number(value))) {
        return Promise.reject('请输入数字')
      }

      if (!/^(([1-9]{1}\d*)|(0{1}))(\.\d{0,2})?$/.test(value)) {
        return Promise.reject('小数点后最多保留两位')
      }

      return Promise.resolve()
    }

    function robotValidator() {
      const robotRatio = trim(formModel.value.robotRatio)
      const robotNum = trim(formModel.value.robotNum)
      const robotFillTime = trim(formModel.value.robotFillTime)
      let len = 0

      if (robotRatio) {
        if (isNaN(Number(robotRatio))) {
          message.warn('机器人 - 团队人数占总人数 - 请输入数字', 1.5)
          return Promise.reject()
        } else {
          formModel.value.robotRatio = robotRatio
        }

        len++
      }

      if (robotNum) {
        if (isNaN(Number(robotNum))) {
          message.warn('机器人 - 临近活动结束时间 - 请输入数字', 1.5)
          return Promise.reject()
        } else {
          formModel.value.robotNum = robotNum
        }

        len++
      }

      if (robotFillTime) {
        if (isNaN(Number(robotFillTime))) {
          message.warn('机器人 - 填充机器人 - 请输入数字', 1.5)
          return Promise.reject()
        } else {
          formModel.value.robotFillTime = robotFillTime
        }

        len++
      }

      if (len > 0 && len < 3) {
        message.warn('机器人 - 三个输入框必须同时填满')
        return Promise.reject()
      }
    }

    /** 上传 */
    function handleUploadChange(key: UploadKey, params: FileInfo) {
      fileList.value[key] = params.fileList

      if (params.file.status === 'done') {
        fileList.value[key].find(v => v.uid === params.file.uid).url =
          params.file.response.data
      }
    }

    /** 选择券码 */
    function handleCouponChange(value: any) {
      formModel.value.stock = couponStockMap.value[value]
    }

    /** 初始化 */
    async function init() {
      try {
        loading.value = true

        const res = await couponApi.getSimpleList({
          type: 2
        })

        couponOptions.value = res.map(v => {
          couponStockMap.value[v.id] = v.stock

          return {
            label: v.name,
            value: v.id
          }
        })

        if (id.value) {
          const res = await marketingApi.getGroupManageItemDetail(id.value)
          res.name = res.name || ''

          res.activityStartTime = res.activityStartTime
            ? (moment(res.activityStartTime, 'x') as any)
            : ''
          res.activityEndTime = res.activityEndTime
            ? (moment(res.activityEndTime, 'x') as any)
            : ''

          Object.assign(formModel.value, res)

          fileList.value.goodsImg = formModel.value.goodsImg
            .split(',')
            .map(v => ({
              uid: Math.random().toString().slice(-5),
              url: v
            }))

          fileList.value.sharePosterImg = [
            {
              uid: Math.random().toString().slice(-5),
              url: formModel.value.sharePosterImg
            }
          ]

          editorConfig.value.editorHtml = res.goodsDescription
        }

        editorConfig.value.editorVisible = true

        if (isDisabled.value) {
          setTimeout(() => {
            editorRef.value.editor.disable()
          }, 300)
        }
      } catch {
      } finally {
        loading.value = false
      }
    }

    /** 提交 */
    async function handleSubmit() {
      const editorHtml = editorRef.value.editor.getHtml()
      const editorText = editorRef.value.editor.getText()

      formModel.value.goodsDescription = editorText
        ? editorHtml
        : editorHtml.includes('<img')
        ? editorHtml
        : ''

      await robotValidator()

      nextTick(() => {
        formRef
          .validate()
          .then(async () => {
            try {
              loading.value = true

              const data = {
                ...formModel.value,
                activityStartTime: moment(
                  formModel.value.activityStartTime
                ).format('x'),
                activityEndTime: moment(formModel.value.activityEndTime).format(
                  'x'
                ),
                goodsImg: fileList.value.goodsImg.map(v => v.url).join(','),
                sharePosterImg: fileList.value.sharePosterImg[0].url
              }

              id.value
                ? await marketingApi.updateGroupManageItem(data)
                : await marketingApi.createGroupManageItem(data)

              handleCancel()
            } finally {
              loading.value = false
            }
          })
          .catch(() => {})
      })
    }

    onMounted(() => {
      init()
    })

    return {
      loading,
      formRef,
      formModel,
      editorRef,
      editorConfig,
      fileList,
      isDisabled,
      isPending,
      couponOptions,
      handleUploadChange,
      handleCouponChange,
      handleCancel,
      handleSubmit
    }
  },
  render() {
    return (
      <div class={styles.groupForm}>
        <Spin spinning={this.loading}>
          <Form labelCol={{ span: 2 }}>
            <FormItem label="活动名称" {...this.formRef.validateInfos['name']}>
              <Input
                v-model:value={this.formModel.name}
                v-slots={{
                  suffix: () => <span>{this.formModel.name.length}/60</span>
                }}
                class={styles.formNormalInput}
                maxlength={60}
                placeholder="请输入拼团活动名称"
                disabled={this.isDisabled}
              />
            </FormItem>
            <FormItem
              label="活动时间"
              {...this.formRef.validateInfos['activityDate']}
            >
              <DatePicker
                v-model:value={this.formModel.activityStartTime}
                placeholder="开始日期"
                disabled={this.isDisabled || this.isPending}
                showTime
              />
              <span style={{ margin: '0 15px' }}>-</span>
              <DatePicker
                v-model:value={this.formModel.activityEndTime}
                placeholder="结束日期"
                disabled={this.isDisabled}
                showTime
              />
            </FormItem>
            <FormItem
              label="订单失效时间"
              {...this.formRef.validateInfos['expireTime']}
            >
              <Input
                v-model:value={this.formModel.expireTime}
                class={styles.formNormalInput}
                placeholder="请输入"
                disabled={this.isDisabled || this.isPending}
              />
              <span class={styles.formDesc}>
                注：自订单创建后失效时间，仅可整数，且不小于1小时，不设置则默认24小时
              </span>
            </FormItem>
            <FormItem
              label="成团数"
              {...this.formRef.validateInfos['groupNumber']}
            >
              <Input
                v-model:value={this.formModel.groupNumber}
                class={styles.formNormalInput}
                placeholder="请输入成团数"
                disabled={this.isDisabled || this.isPending}
              />
            </FormItem>
            <FormItem label="排序" {...this.formRef.validateInfos['sort']}>
              <Input
                v-model:value={this.formModel.sort}
                class={styles.formNormalInput}
                placeholder="请输入"
                disabled={this.isDisabled}
              />
            </FormItem>
            <FormItem
              label="拼团券码"
              {...this.formRef.validateInfos['groupCoupon']}
            >
              <Select
                v-model:value={this.formModel.groupCoupon}
                class={['groupCoupon', styles.formNormalInput]}
                placeholder="请选择"
                getPopupContainer={() => document.querySelector('.groupCoupon')}
                disabled={this.isDisabled || this.isPending}
                onChange={this.handleCouponChange}
              >
                {this.couponOptions.map(v => (
                  <SelectOption value={v.value}>{v.label}</SelectOption>
                ))}
              </Select>
            </FormItem>
            <FormItem label="可兑库存" {...this.formRef.validateInfos['stock']}>
              <Input
                v-model:value={this.formModel.stock}
                class={styles.formNormalInput}
                disabled
              />
            </FormItem>
            <FormItem label="市场价" {...this.formRef.validateInfos['price']}>
              <Input
                v-model:value={this.formModel.price}
                v-slots={{
                  prefix: () => '￥'
                }}
                class={styles.formNormalInput}
                placeholder="请输入"
                disabled={this.isDisabled || this.isPending}
              />
            </FormItem>
            <FormItem
              label="拼团价"
              {...this.formRef.validateInfos['groupPrice']}
            >
              <Input
                v-model:value={this.formModel.groupPrice}
                v-slots={{
                  prefix: () => '￥'
                }}
                class={styles.formNormalInput}
                placeholder="请输入"
                disabled={this.isDisabled || this.isPending}
              />
            </FormItem>
            <FormItem label="机器人">
              <span>团队人数占总人数</span>
              <Input
                v-model:value={this.formModel.robotRatio}
                class={styles.formMiniInput}
                disabled={this.isDisabled || this.isPending}
              />
              <span>%，临近活动结束时间</span>
              <Input
                v-model:value={this.formModel.robotFillTime}
                class={styles.formMiniInput}
                disabled={this.isDisabled || this.isPending}
              />
              <span>小时，填充</span>
              <Input
                v-model:value={this.formModel.robotNum}
                class={styles.formMiniInput}
                disabled={this.isDisabled || this.isPending}
              />
              <span>机器人</span>
            </FormItem>
            <FormItem
              label="分享海报图"
              {...this.formRef.validateInfos['sharePosterImg']}
            >
              <Upload
                action={commonApi.uploadFileUrl}
                accept="image/*"
                listType="picture-card"
                fileList={this.fileList.sharePosterImg}
                showUploadList={{
                  showPreviewIcon: false,
                  showRemoveIcon: true
                }}
                onChange={args =>
                  this.handleUploadChange('sharePosterImg', args)
                }
                disabled={this.isDisabled}
              >
                {this.fileList.sharePosterImg.length === 0 ? (
                  <div>
                    <SvgIcon name="upload" />
                    <div class="ant-upload-text"></div>
                  </div>
                ) : null}
              </Upload>
              <span class={styles.formDesc}>注：建议尺寸750*960</span>
            </FormItem>
            <FormItem
              label="商品图片"
              {...this.formRef.validateInfos['goodsImg']}
            >
              <Upload
                action={commonApi.uploadFileUrl}
                accept="image/*"
                listType="picture-card"
                fileList={this.fileList.goodsImg}
                showUploadList={{
                  showPreviewIcon: false,
                  showRemoveIcon: true
                }}
                onChange={args => this.handleUploadChange('goodsImg', args)}
                disabled={this.isDisabled}
              >
                {this.fileList.goodsImg.length < 5 && !this.isDisabled ? (
                  <div>
                    <SvgIcon name="upload" />
                    <div class="ant-upload-text"></div>
                  </div>
                ) : null}
              </Upload>
              <span class={styles.formDesc}>注：建议200*200像素</span>
            </FormItem>
            <FormItem
              label="商品描述"
              {...this.formRef.validateInfos['goodsDescription']}
            >
              <ProEditor ref="editorRef" {...this.editorConfig} />
            </FormItem>
            <FormItem
              label="拼团次数上限"
              {...this.formRef.validateInfos['amalgamateGroupLimit']}
            >
              <Input
                v-model:value={this.formModel.amalgamateGroupLimit}
                class={styles.formNormalInput}
                placeholder="请输入"
                disabled={this.isDisabled || this.isPending}
              />
              <span class={styles.formDesc}>
                注：一次只能参团一个，默认为0没有上限
              </span>
            </FormItem>
            <FormItem
              label="开团次数上限"
              {...this.formRef.validateInfos['openGroupLimit']}
            >
              <Input
                v-model:value={this.formModel.openGroupLimit}
                class={styles.formNormalInput}
                placeholder="请输入"
                disabled={this.isDisabled || this.isPending}
              />
              <span class={styles.formDesc}>注：默认为0没有上限</span>
            </FormItem>
            <Divider />
            <FormItem class={styles.formBtns}>
              <Space>
                <Button class={styles.formBtn} onClick={this.handleCancel}>
                  取消
                </Button>
                {!this.isDisabled ? (
                  <Button
                    class={styles.formBtn}
                    type="primary"
                    onClick={this.handleSubmit}
                  >
                    保存
                  </Button>
                ) : null}
              </Space>
            </FormItem>
          </Form>
        </Spin>
      </div>
    )
  }
})
